from typing import List, Optional

from sqlalchemy import BigInteger, Boolean, DateTime, Enum, ForeignKeyConstraint, Integer, JSON, PrimaryKeyConstraint, String, Text
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
import datetime

class Base(DeclarativeBase):
    pass


class Dogs(Base):
    __tablename__ = 'dogs'
    __table_args__ = (
        PrimaryKeyConstraint('dog_code', name='dogs_pkey'),
    )

    dog_code: Mapped[str] = mapped_column(String(50), primary_key=True, comment='编号')
    video_url: Mapped[Optional[str]] = mapped_column(Text, comment='视频流链接')
    ip_address: Mapped[Optional[str]] = mapped_column(String(50), comment='IP地址')

    operation_tickets: Mapped[List['OperationTickets']] = relationship('OperationTickets', back_populates='dogs')


class Users(Base):
    __tablename__ = 'users'
    __table_args__ = (
        PrimaryKeyConstraint('id', name='users_pkey'),
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    username: Mapped[str] = mapped_column(String(100), comment='用户名')
    phone_num: Mapped[str] = mapped_column(String(20), comment='手机号')
    password: Mapped[str] = mapped_column(String(255), comment='密码')
    is_admin: Mapped[Optional[bool]] = mapped_column(Boolean, comment='是否为管理员')
    emp_number: Mapped[Optional[str]] = mapped_column(Text, comment='工号')
    position: Mapped[Optional[int]] = mapped_column(BigInteger, comment='职位')
    department: Mapped[Optional[int]] = mapped_column(Integer, comment='部门')

    operation_tickets: Mapped[List['OperationTickets']] = relationship('OperationTickets', foreign_keys='[OperationTickets.issuer_id]', back_populates='issuer')
    operation_tickets_: Mapped[List['OperationTickets']] = relationship('OperationTickets', foreign_keys='[OperationTickets.operator_id]', back_populates='operator')


class OperationTickets(Base):
    __tablename__ = 'operation_tickets'
    __table_args__ = (
        ForeignKeyConstraint(['issuer_id'], ['users.id'], name='operation_tickets_issuer_id_fkey'),
        ForeignKeyConstraint(['operator_id'], ['users.id'], name='operation_tickets_operator_id_fkey'),
        ForeignKeyConstraint(['patrol_dog_code'], ['dogs.dog_code'], name='operation_tickets_patrol_dog_code_fkey'),
        PrimaryKeyConstraint('ticket_code', name='operation_tickets_pkey')
    )

    ticket_code: Mapped[str] = mapped_column(String(50), primary_key=True, comment='票号')
    company: Mapped[str] = mapped_column(String(100), comment='公司')
    task: Mapped[str] = mapped_column(Text, comment='操作任务')
    start_time: Mapped[datetime.datetime] = mapped_column(DateTime, comment='开始时间')
    end_time: Mapped[datetime.datetime] = mapped_column(DateTime, comment='结束时间')
    issuer_id: Mapped[int] = mapped_column(Integer, comment='开具人员')
    facility_code: Mapped[str] = mapped_column(String(255), comment='操作柜编号')
    operator_id: Mapped[Optional[int]] = mapped_column(Integer, comment='操作人')
    patrol_dog_code: Mapped[Optional[str]] = mapped_column(String(50), comment='巡检狗')
    status: Mapped[Optional[str]] = mapped_column(Enum('待检查', '异常', '正常', name='status'), comment='状态')
    remarks: Mapped[Optional[str]] = mapped_column(Text, comment='备注详细')
    abnormal_reason: Mapped[Optional[str]] = mapped_column(Text, comment='异常票原因，状态为异常时必填')

    issuer: Mapped['Users'] = relationship('Users', foreign_keys=[issuer_id], back_populates='operation_tickets')
    operator: Mapped[Optional['Users']] = relationship('Users', foreign_keys=[operator_id], back_populates='operation_tickets_')
    dogs: Mapped[Optional['Dogs']] = relationship('Dogs', back_populates='operation_tickets')
    apparatus_states: Mapped[List['ApparatusStates']] = relationship('ApparatusStates', back_populates='operation_tickets')


class ApparatusStates(Base):
    __tablename__ = 'apparatus_states'
    __table_args__ = (
        ForeignKeyConstraint(['ticket_code'], ['operation_tickets.ticket_code'], name='apparatus_states_ticket_code_fkey'),
        PrimaryKeyConstraint('id', name='apparatus_states_pkey')
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    ticket_code: Mapped[str] = mapped_column(String(50), comment='绑定票号')
    dog_code: Mapped[Optional[str]] = mapped_column(String(255), comment='巡检狗编号')
    facility_status: Mapped[Optional[dict]] = mapped_column(JSON, comment='装置状态')

    operation_tickets: Mapped['OperationTickets'] = relationship('OperationTickets', back_populates='apparatus_states')
